#!/usr/bin/python3
# -*- coding: utf8 -*-
# Date   : 2021/07/22
# Author : Kwan
# Email  : allenxian@live.com
# Blog   : https://my.oschina.net/u/4173440

from datetime import datetime
from flask import json, url_for, abort
from project.define import AxiosMessage, page_logger
from project.modules import ChargeClasses, ChargeDetail, RecordParking, CarParkRule, MemberUser, CarParkPlace
from project.prepare import CarParkService


"""
收费功能：
1.时租收费：获取在场记录 => 发起收费 => 返回结果
2.补票 => 新增/修改在场记录 => 返回结果
3.月租收费：获取有效月租 => 发起收费 => 返回结果
"""

class Messager(AxiosMessage):
    """
    消息管理器
    """
    def __init__(self) -> None:
        super().__init__()

    def __generate_page_data(self, *args):
        """
        生成页面数据
        """
        return {
            "ColumnName":args[0], 
            "ColumnNameJSON": json.dumps(args[0],ensure_ascii=False), 
            "TableDatas": args[1],
            "Filters": args[2],
            "FiltersJSON": json.dumps(args[2],ensure_ascii=False),
        }

    def __get_hourly_parking(self, **kwargs):
        """
        获取有效在场记录
        """
        filters = set()
        filters.add(RecordParking.ParkingType=="Hourly")
        filters.add(RecordParking.ExitTime==None)
        filters.add(RecordParking.Deleted==False)
        licenseplate = kwargs.get("LicensePlate")
        if licenseplate:
            filters.add(RecordParking.LicensePlate==licenseplate)
        ticket_number = kwargs.get("TicketNumber")
        if ticket_number:
            filters.add(RecordParking.TicketNumber==ticket_number)
        p = RecordParking.query.filter(*filters).first()
        if p:
            return self.json_data(**p.to_dict())
        return abort(500)

    def __get_monthly_user(self, **kwargs):
        """
        获取有效月租
        """
        filters = set()
        filters.add(MemberUser.ParkingType=="Monthly")
        filters.add(MemberUser.Enable==True)
        licenseplate = kwargs.get("LicensePlate")
        if licenseplate:
            filters.add(MemberUser.LicensePlate.like(f"%{licenseplate}%"))
        card_number = kwargs.get("CardNumber")
        if card_number:
            filters.add(MemberUser.CardNumber==card_number)
        m = MemberUser.query.filter(*filters).first()
        if m:
            return self.json_data(**m.to_dict())
        return abort(500)

    
    def __generate_ticket(self, **data):
        """
        补票，新建或修改
        """
        data['ParkingType'] = 'Hourly'
        parking_id = data.get('ParkingID')
        if not parking_id:
            # 新建
            data['GateName'] = data['CashierName']
            data['EntranceID'] = 0
            data['TicketNumber'] = datetime.now().strftime("%Y%m%d%H%M%S")
            ret = RecordParking.lane_entrance_record(**data)
            if ret:
                return self.success("補票成功")
        else:
            # 修改
            p = RecordParking.query.filter_by(ParkingID=parking_id,Deleted=False).first()
            if p:
                ret = p.modify_ticket_parking(**data)
                if ret:
                    return self.success("補票成功")
        return self.success("補票失敗")

    def __get_data(self, view, **data):
        """
        获取数据
        """
        if view == "preview":
            parking_type = data.get('ParkingType')
            licenseplate = data.get('LicensePlate')
            if parking_type == "Hourly":
                r = RecordParking.query.filter_by(LicensePlate=licenseplate,ParkingType=parking_type,ExitTime=None,Deleted=False).first()
                if r:
                    ret = r.to_dict()
                    image = ret.get('LicensePlateImg')
                    if image:
                        ret['LicensePlateImg'] = url_for('static',filename=image)
                    charge_time = ret.get('ChargeTime')
                    if charge_time:
                        ret['EntranceTime'] = charge_time
                    cost = CarParkRule.generate_hourly_parking_cost(**ret)
                    if cost:
                        ret.update(**cost)
                    return self.json_data(**ret)
            return self.error("沒有在場記錄")
        elif view == "classes":
            ret = ChargeDetail.query.filter_by(ChargeID=data.get('ChargeID')).first()
            if ret:
                return self.json_data(**ret.to_dict())
        return self.error("請求錯誤")

    def __upbar_data(self, **data):
        """
        起杆
        """
        CarParkService.UpBarQ.put(data)
        return self.success("發送起杆成功")

    def __hourly_pay(self, **kwargs):
        """
        时租付费
        """
        parking_id = kwargs.get("ParkingID")
        p = RecordParking.query.filter_by(ParkingID=parking_id,Deleted=False).first()
        if p:
            licenseplate = kwargs.get('LicensePlate')
            if p.LicensePlate == licenseplate:
                kwargs['ChargeType'] = p.ParkingType
                ret = ChargeDetail.parking_charge(**kwargs)
                if ret:
                    p.refresh_charge_info(**ret)
                    return self.success("付費成功")
        return self.warning("付費失敗")

    def __monthly_pay(self, **kwargs):
        """
        月租付费
        """
        user_id = kwargs.get('UserID')
        if user_id:
            m = MemberUser.query.filter_by(UserID=user_id).first()
            if not m:
                return self.error("月租無效")
            if not m.Enable:
                return self.error("月租已停用")
            kwargs['ChargeType'] = m.ParkingType
            ret = ChargeDetail.parking_charge(**kwargs)
            if ret:
                paid = m.parking_valid_renewal(**kwargs)
                if paid:
                    return self.success("付費成功")
        return self.warning("付費失敗")

    def __get_monthly(self, **kwargs):
        """
        获取月租用户
        """
        lp = kwargs.get('LicensePlate')
        if lp:
            # 月租是否存在
            m = MemberUser.query.filter(MemberUser.LicensePlate.like(f"%{lp}%"),MemberUser.ParkingType=="Monthly").first()
            if m:
                if not m.Enable:
                    return self.error("月租已停用")
                ret = m.to_dict()
                p = CarParkPlace.query.filter_by(VehicleType=m.VehicleType,ParkingType=m.ParkingType).first()
                if p:
                    # 是否存在车位
                    r = CarParkRule.query.filter_by(VehicleType=m.VehicleType,ParkingType=m.ParkingType).first()
                    if r:
                        # 是否存在收费规则
                        ret['Price'] = r.Price
                        ret['Money'] = r.Price
                return self.json_data(**ret)
        return self.error("月租無效")

    def __get_charge_classes_total(self, **data):
        """
        获取更次总结
        """
        classes_id = data.get('ClassesID')
        if classes_id:
            charges = ChargeDetail.query.filter_by(ClassesID=classes_id,Deleted=False).all()
            if charges:
                current_classes = ChargeClasses.query.filter_by(ClassesID=classes_id).first()
                ret = current_classes.to_dict()
                income = []
                ret['Cash'] = sum([i.Money for i in charges if i.PayMent == "Cash"])
                ret['UnionPay'] = sum([i.Money for i in charges if i.PayMent == "UnionPay"])
                ret['MacauPay'] = sum([i.Money for i in charges if i.PayMent == "MacauPay"])
                ret['AliPay'] = sum([i.Money for i in charges if i.PayMent == "AliPay"])
                ret['WeChatPay'] = sum([i.Money for i in charges if i.PayMent == "WeChatPay"])
                ret['MPay'] = sum([i.Money for i in charges if i.PayMent == "MPay"])
                for k, v in ret.items():
                    if k in ('Cash','UnionPay','MacauPay','AliPay','WeChatPay','MPay'):
                        if v > 0:
                            income.append(v)
                ret['Income'] = sum(income)
                return self.json_data(**ret)
        return self.error("請求錯誤")

    def __delete_charge_detail(self, **data):
        """
        删除收费明细
        """
        charge_id = data.get('ChargeID')
        if charge_id:
            if ChargeDetail.delete_data(**data):
                return self.success("刪除收費記錄成功")
        return self.warning("刪除收費記錄失敗")

    def post_data_handler(self, **kwargs):
        """
        页面交互数据
        """
        view = kwargs.pop("View")
        for k, v in kwargs.items():
            if k == "UpBar":
                return self.__upbar_data(**v)
            elif k == "GetData":
                return self.__get_data(view, **v)
            elif k == "GetClasses":
                cashier_info = kwargs.get('CashierInfo')
                v.update(**cashier_info)
                return self.__get_charge_classes_total(**v)
            elif k == "GetTicket":
                cashier_info = kwargs.get('CashierInfo')
                v.update(**cashier_info)
                return self.__generate_ticket(**v)
            elif k == "GetMonthly":
                return self.__get_monthly(**v)
            elif k == "Hourly":
                cashier_info = kwargs.get('CashierInfo')
                v.update(**cashier_info)
                return self.__hourly_pay(**v)
            elif k == "Monthly":
                cashier_info = kwargs.get('CashierInfo')
                v.update(**cashier_info)
                return self.__monthly_pay(**v)
            elif k == "Delete":
                return self.__delete_charge_detail(**v)


    def cashier_preview_data(self):
        """
        预览页面数据
        """
        pass

    def cashier_classes_data(self, classes_id, cashier_name, user_name):
        """
        更次收费记录
        """
        c = ChargeClasses.query.filter_by(ClassesID=classes_id).first()
        table_datas = ChargeDetail.query.filter_by(ClassesID=classes_id,Deleted=False).all()
        column_name = ChargeDetail.column_name()
        ret = self.__generate_page_data(*[column_name, table_datas, None])
        ret['ClassesID'] = classes_id
        ret['CashierName'] = cashier_name
        ret['UserName'] = user_name
        ret['StartTime'] = c.StartTime.strftime('%Y/%m/%d %H:%M:%S')
        ret['ClassesNameJSON'] = json.dumps(ChargeClasses.columns_name())
        return ret
